/* 
 * File:   CoreTimerDelay.h
 * Author: frank
 *
 * Created on November 29, 2014, 3:18 PM
 *
 * This library is used to schedule small precise delays.
 * The client can schedule several delays so that no other client can use
 * the timer.  This feature requires the use of the core timer so no other
 * service may use this timer.
 *
 * The SYS_CLK_FREQ must be defined somewhere for the main clock.  This is
 * done in Harmony in the system_config.h file.  This file is included so if
 * Harmony is not used then either the #include should be removed and a
 * #define of the SYS_CLK_FREQ should be done or create the file and put
 * the define in it.
 *
 * The number of clients, number of allowed delays, and interrupt used are
 * configured below.  The client call backs are always looped through so
 * the bigger the number the longer the interrupt takes.  Make the number
 * as small as possible.  Clients can connect and disconnect when they need
 * the delay so keeping the number small should not be a problem.
 */

#ifndef CORETIMERDELAY_H
#define	CORETIMERDELAY_H

#include <stdint.h>
#include <stdbool.h>
#include "system_config.h"


// Number of clients.  Used for call back functions
#define COREDELAY_MAXCLIENTS 3
// Number of delays that can be scheduled by a single client
// Only one client at a time can use the core delay
#define COREDELAY_MAXIDS 3
// Sets the interrupt priority of the core timer from 0 to 7
#define COREDELAY_PRIORITY 5
// Sets the sub priority of the core timer from 0 to 3
#define COREDELAY_SUBPRIORITY 0

#if COREDELAY_PRIORITY == 0
    #define COREDELAY_IP CT_INT_PRIOR_0
    #define COREDELAY_INT ipl0
#elif COREDELAY_PRIORITY == 1
    #define COREDELAY_IP CT_INT_PRIOR_1
    #define COREDELAY_INT ipl1
#elif COREDELAY_PRIORITY == 2
    #define COREDELAY_IP CT_INT_PRIOR_2
    #define COREDELAY_INT ipl2
#elif COREDELAY_PRIORITY == 3
    #define COREDELAY_IP CT_INT_PRIOR_3
    #define COREDELAY_INT ipl3
#elif COREDELAY_PRIORITY == 4
    #define COREDELAY_IP CT_INT_PRIOR_4
    #define COREDELAY_INT ipl4
#elif COREDELAY_PRIORITY == 5
    #define COREDELAY_IP CT_INT_PRIOR_5
    #define COREDELAY_INT ipl5
#elif COREDELAY_PRIORITY == 6
    #define COREDELAY_IP CT_INT_PRIOR_6
    #define COREDELAY_INT ipl6
#elif COREDELAY_PRIORITY == 7
    #define COREDELAY_IP CT_INT_PRIOR_7
    #define COREDELAY_INT ipl7
#endif
#if COREDELAY_SUBPRIORITY == 0
    #define COREDELAY_ISP CT_INT_SUB_PRIOR_0
#elif COREDELAY_SUBPRIORITY == 1
    #define COREDELAY_ISP CT_INT_SUB_PRIOR_1
#elif COREDELAY_SUBPRIORITY == 2
    #define COREDELAY_ISP CT_INT_SUB_PRIOR_2
#elif COREDELAY_SUBPRIORITY == 3
    #define COREDELAY_ISP CT_INT_SUB_PRIOR_3
#endif

// Callback for async delay
typedef void (*CoreDelay_DelayCallback)(uint8_t id);
typedef void (*CoreDelay_BusyCallback)(bool busy);

void CoreDelay_Init();
// Returns true if added
bool CoreDelay_SetDelayCallback(CoreDelay_DelayCallback function);
bool CoreDelay_SetBusyCallback(CoreDelay_BusyCallback function);
void CoreDelay_RemoveDelayCallback(CoreDelay_DelayCallback function);
void CoreDelay_RemoveBusyCallback(CoreDelay_BusyCallback function);

// Returns true if in use
bool CoreDelay_Busy();
// Returns true on success or false if busy with other client
bool CoreDelay_Sync_us(unsigned int us);
// Returns true on success or false if busy
bool CoreDelay_Async_us1(unsigned int us1);
// If oneShot is true the client must call Next to start next delay
bool CoreDelay_Async_us2(bool oneShot, unsigned int us1, unsigned int us2);
bool CoreDelay_Async_us3(bool oneShot, unsigned int us1, unsigned int us2, unsigned int us3);
// If size > COREDELAY_MAXIDS will return false
bool CoreDelay_Async_usA(bool oneShot, unsigned int* usA, uint8_t size);
// Returns true if delay is started.
bool CoreDelay_Next();
// Clears pending delays
void CoreDelay_Abort();

#endif	/* CORETIMERDELAY_H */

